package com.up.vms.infrastructure.security;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import java.io.*;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Enumeration;

@Slf4j
public class CertUtil {

    private CertUtil() {
        // do nothing
    }


    /**
     * 从文件中加载私钥
     *
     * @param in
     * @return
     * @throws Exception
     */
    public static PrivateKey loadPrivateKey(InputStream in) throws Exception {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String readLine = null;
            StringBuilder sb = new StringBuilder();
            while ((readLine = br.readLine()) != null) {
                if (readLine.charAt(0) == '-') {
                    continue;
                } else {
                    sb.append(readLine);
                    sb.append(System.getProperty("line.separator"));
                }
            }
            return loadPrivateKey(sb.toString());
        } catch (IOException e) {
            throw new Exception("私钥数据读取错误");
        } catch (NullPointerException e) {
            throw new Exception("私钥输入流为空");
        }
    }

    /**
     * 从字符串中加载私钥
     *
     * @param privateKeyStr
     * @return
     * @throws Exception
     */
    public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception{
        try {
            byte[] buffer = Base64.decodeBase64(privateKeyStr);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePrivate(keySpec);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此算法");
        } catch (InvalidKeySpecException e) {
            throw new Exception("私钥非法");
        } catch (NullPointerException e) {
            throw new Exception("私钥数据为空");
        }
    }

    public static PrivateKey getPrivateKeyInfo(String path, String pwd) throws Exception {
        String privKeyFileString = path;
        String privKeyPswdString = pwd;
        String keyAlias = null;
        PrivateKey prikey;

        try (
            FileInputStream fileInputStream = new FileInputStream(privKeyFileString)
        ){
            KeyStore keyStore = KeyStore.getInstance("PKCS12");

            char[] nPassword;
            if ((privKeyPswdString == null) || privKeyPswdString.trim().equals("")) {
                nPassword = null;
            } else {
                nPassword = privKeyPswdString.toCharArray();
            }
            keyStore.load(fileInputStream, nPassword);

            log.info("keystore type={}", keyStore.getType());

            Enumeration<String> enumeration = keyStore.aliases();

            if (enumeration.hasMoreElements()) {
                keyAlias = enumeration.nextElement();
                log.info("alias=[{}]", keyAlias);
            }
            log.info("is key entry={}", keyStore.isKeyEntry(keyAlias));
            prikey = (PrivateKey) keyStore.getKey(keyAlias, nPassword);
        } catch (Exception e) {
            throw new Exception(e);
        }
        return prikey;
    }
}
